/*
 *      dilca-sensor-samhain-net.c
 *
 *      Copyright 2009 Daniele Ricci <denn86@gmail.com>, Luca Saccagi <luksak86@gmail.com>
 *
 *      This program is free software; you can redistribute it and/or modify
 *      it under the terms of the GNU General Public License as published by
 *      the Free Software Foundation; either version 2 of the License, or
 *      (at your option) any later version.
 *
 *      This program is distributed in the hope that it will be useful,
 *      but WITHOUT ANY WARRANTY; without even the implied warranty of
 *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *      GNU General Public License for more details.
 *
 *      You should have received a copy of the GNU General Public License
 *      along with this program; if not, write to the Free Software
 *      Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
 *      MA 02110-1301, USA.
 */

#define _VERSION "dilca - Samhain Net Sensor (v0.0.3)"
#define _VERSION1 "0.0.3"


#include <stdio.h>
#include <errno.h>
#include <ctype.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <libidxp.h>
#include "lightlog.c"

void version(int argc, char **argv){
        if(argc <= 1) return;
        if(strcmp(argv[1],"-v")==0){ printf(_VERSION1); printf("\n"); exit(0); }
        if(strcmp(argv[1],"-V")==0){ printf(_VERSION); printf("\n"); exit(0); }
        return;
}

char *translating_log(char *buffer_log, int buffer_len, char *analyzer_id, int message_id){
        int index=0;
        int i=0,j=0;
        time_t ttime;
        char severity[5];
        char timestamp_hex[22];
        char timestamp_human[25];
        char *AdditionalData_list=NULL,*AdditionalData_tmp;
        char AdditionalData_meaning[1000],AdditionalData_content[10000];
	char *returnpointer=NULL;
        struct tm tmtime,tmtime2;

        AdditionalData_list=(char*)calloc(20000,sizeof(char));
        AdditionalData_list[0]='\0';

        /* Retrieving severity */
	/* <idmef:Assessment><idmef:Impact severity="high" completion="succeeded" type="admin"/> it would be like this, but due to deeper severity levels, we
           cannot map samhain severity directly onto <impact> severity parameter... */
        strncpy(severity,buffer_log,4);
	AdditionalData_tmp=lightlog_idmef_child(IDMEF_STDPAT_ADDITIONALDATA,"string","severity",severity,0,0,0);
        strcat(AdditionalData_list,AdditionalData_tmp);
        free(AdditionalData_tmp);

        /* Retrieving Timestamp & HEXTimestamp */
        sscanf(&buffer_log[10],"[%4d-%02d-%02dT%02d:%02d:%02d%*s",&tmtime.tm_year,&tmtime.tm_mon,&tmtime.tm_mday,&tmtime.tm_hour,&tmtime.tm_min,&tmtime.tm_sec);
        sprintf(timestamp_human,"%d-%d-%dT%d:%d:%dZ\0",tmtime.tm_year,tmtime.tm_mon,tmtime.tm_mday,tmtime.tm_hour,tmtime.tm_min,tmtime.tm_sec);
        tmtime.tm_mon-=1;
        tmtime.tm_year-=1900;
        ttime=mktime(&tmtime);
        sprintf(timestamp_hex,"0x%08lX.0x00000000\0",ttime);
        //Localtime_m(&tmtime2,&ttime);
        //printf("[%d-%d-%dT%d:%d:%d]\n",tmtime2.tm_year+1900,tmtime2.tm_mon+1,tmtime2.tm_mday,tmtime2.tm_hour,tmtime2.tm_min,tmtime2.tm_sec);
        //printf("TSH -> %s\nTSX -> %s\n",timestamp_human,timestamp_hex);



        for(i=0;i<buffer_len;i++){
                /* Retrieving AdditionalData meaning */
                switch(buffer_log[i]){
                        case ']':
				i++; i++;
                                sscanf(&buffer_log[i],"%1000[^=]%*c%*c%10000[^>]",AdditionalData_meaning,AdditionalData_content);
				i+=strlen(AdditionalData_meaning)+strlen(AdditionalData_content)+1;
                                AdditionalData_tmp=lightlog_idmef_child(IDMEF_STDPAT_ADDITIONALDATA,"string",AdditionalData_meaning,AdditionalData_content,0,0,0);
                                strcat(AdditionalData_list,AdditionalData_tmp);
                                free(AdditionalData_tmp);
                        break;
                        case ',':
				i++; i++;
                                sscanf(&buffer_log[i],"%1000[^=]%*c%*c%[^>]s",AdditionalData_meaning,AdditionalData_content);
				i+=strlen(AdditionalData_meaning)+strlen(AdditionalData_content)+1;
                                AdditionalData_tmp=lightlog_idmef_child(IDMEF_STDPAT_ADDITIONALDATA,"string",AdditionalData_meaning,AdditionalData_content,0,0,0);
                                strcat(AdditionalData_list,AdditionalData_tmp);
                                free(AdditionalData_tmp);
				AdditionalData_content[0]='\0';
				AdditionalData_meaning[0]='\0';
                        break;
                        default:
                        break;
                 }
        }

        returnpointer= lightlog_idmef_alert_create(analyzer_id,message_id,
                        lightlog_idmef_child(IDMEF_STDPAT_ANALYZER,analyzer_id,"",NULL,0,0,0),
                        lightlog_idmef_child("CreateTime","<%s ntpstamp=\"%s%s\">%s</%s>\0","",timestamp_hex,timestamp_human,0,0,0),
			lightlog_idmef_child(IDMEF_STDPAT_CLASSIFICATION,"Samhain Integrity Monitor Agent","",NULL,0,0,0),
                        AdditionalData_list);
	return returnpointer;
}


int main(int argc, char *argv[]){
    	int ret_val, count, numread, i;
    	char buf[5000],TMPBUF[500],TMPBUF2[500];
	char *idmef=NULL,*callocated=NULL;
	int message_id=0,log_max_size=0,logrot=0;
	FILE *fd=NULL,*fl=NULL;
	char c;
	IdxpConnection *connection=NULL;
	IdxpChannel *channel=NULL;

	version(argc,argv);

	IDXPLIB_INITIATOR

	/* Loading IDXP configuration */
	(argc==6) ? idxp_configuration_load(argv[3],NULL) : (printf("\nUsage: %s <named-pipe> <analyzer-id> <idxp-conf> <ip-addr> <ip-port>\n",argv[0]) , exit(-1));

	/* Attempting connection to dilca-gateway */
	connection=idxp_connection_start(connection,argv[4],argv[5],idxp_configuration_get("usr",NULL),idxp_configuration_get("pw",NULL));
        channel=idxp_channel_new(connection,1,"localhost",0,"client",idxp_configuration_get("uri",NULL),idxp_configuration_get("fqdn",NULL),"alert");
	(!(connection && channel)) ? (printf("ERR - unable to connect to %s:%s, exiting ..\n",argv[4],argv[5]) , exit(-2)) : 0;

    	/* Create the named - pipe */
    	ret_val = mkfifo(argv[1], 0666);
    	if(ret_val == -1) 0;//perror("Error creating the named pipe");

    	/* Open the pipe for reading */
    	fd = fopen(argv[1],"r");

    	/* Read from the pipe */
    	while(1){
		i=0;
		while((buf[i++] = fgetc(fd))!='\n') if(buf[i-1] == EOF){fclose(fd); return 0;}
		buf[--i]='\0';
		printf("R(%s)\n",buf);
    		idmef=translating_log(buf,i,argv[2],message_id++);
		printf("R(%s)\n",idmef);
		idxp_channel_send_msg(channel,idmef);
    		idmef == NULL ? 0 : free(idmef);
    	}
	
	/* Closing dilca-gateway connection */
	usleep(100000);
	idxp_channel_close(channel);
	idxp_connection_close(connection);
	return 0;
}


